﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using System.Windows.Forms;
using PowerMonitor.Properties;

namespace PowerMonitor.BaseCtrl
{   
    /// <summary>
    /// 数据类型
    /// </summary>
    public enum eDataType
    {
        BYTE,
        WORD,// show in binary
        SHORT,
        USHORT,
        INT32,
        UINT32,
        FLOAT,
        LONG,
        DOUBLE,
        BCD8,       // 4字节压缩BCD码 （两个寄存器 高字在前 ）
        BCD6_2,     // 4字节压缩BCD码 带2位小数 如报文为0x500265 实际值为 5002.65
        BCD4_4,
        BCD4,
        BCD1_3,
        BCD2_2,
    }
    public enum eByteSqueue
    {
        高位在前 = 0,
        低位在前 = 1,
        高字在前 = 2,
        低字在前 = 3,
        三四一二 = 4
    }
    

   
    [StructLayout(LayoutKind.Sequential)]
    public struct DeviceUnit
    {
        public DeviceUnit(string strName)
        {
            m_DevCnt++;
            m_PointNo = 0;
            m_IDNo = m_DevCnt;
            m_DevName = strName;

            m_FreshTime = DateTime.Now;

        }
        public static int m_DevCnt = 0; // 装置个数
        public int		        m_PointNo;
        public long	            m_IDNo;
        public string           m_DevName;
        public DateTime m_FreshTime;       
    }
    [StructLayout(LayoutKind.Sequential)]
    public abstract class BaseDevice
    {
        public byte bAddr;
        private int _DevId;
        private bool _isConnected;                // 连接状态
        private bool _isWorking;                  // 是否启用
        private int _iNoReceive = 1;              // 连续无接收次数
        private int _BreakCnt;                    // 无接收时连续发送次数 
        public int DeviceId { get { return _DevId; } set { if (value >= 0) _DevId = value; } }
        public int ChannelId { get; set; }
        public bool isConnected { get { return _isConnected; } }                  // 连接状态
        public bool isWorking // 是否启用
        { 
            get { return _isWorking; } 
            set 
            { 
                _isWorking = value;
                if (value == false)
                {
                    _isConnected = false;
                }
            } 
        }                        
        public int NotRecieveCnt     // 连续无接收次数
        { 
            get { return _iNoReceive; } 
            set 
            {
                if (value >= 0) 
                _iNoReceive = value;
                if (_iNoReceive >= BreakOffCnt)
                {
                    _isConnected = false;
                }
                else
                {
                    _isConnected = true;
                }
            } 
        }
        public int BreakOffCnt { get { return _BreakCnt; } set { if (value >= 0) _BreakCnt = value; } }          // 中断条件 m_iNoReceive >= m_iBreakCnt
        private int _iMaxSend = 2;

        public int MaxSendCnt
        {
            get { return _iMaxSend; }
            set { _iMaxSend = value; }
        }

        // 脚本
        ScriptScope scode = null;
        private CompiledCode sourceCode = null;    // 编译的脚本
        private StringBuilder expression = new StringBuilder();
        public string Expression                    // 用于脚本的表达式
        {
            get { return expression.ToString(); }
            set
            {
                if (expression.ToString() != value)
                {
                    expression.Clear();
                    expression.Append(value);
                    try
                    {
                        var code = AppMain.ScptEngine.CreateScriptSourceFromString(expression.ToString());
                        sourceCode = code.Compile();
                    }
                    catch (System.Exception ex)
                    {
                        sourceCode = null;
                        MessageBox.Show(ex.Message);
                    }
                }
            }
        }
        public bool ExecuteScript()                 // 自定义显示
        {
            if (sourceCode != null)
            {
                try
                {
                    if (scode == null)
                    {
                        scode = AppMain.ScptEngine.CreateScope();
                        scode.SetVariable("DataList", m_DataList);  // 设置全局变量
                    }
                    var actual = sourceCode.Execute<object>(scode); //执行code脚本，获取输出值
                }
                catch
                {
                    sourceCode = null;
                    scode = null;
                    return false;
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        public DateTime m_FreshTime;                // 更新时间
        public string Name;                    // 装置名称
        public  DevDataItem GetDataItem(int Index)
        {
            return (Index >= 0 && Index < m_DataList.Count) ? m_DataList[Index] : null;
        }
        public  int GetDataItemCnt()
        {
            return m_DataList.Count;
        }
        public List<DevDataItem> GetDataList()
        {
            return m_DataList;
        }
        public eByteSqueue byteSqueue;              // 字节顺序 hide
        protected List<DevDataItem> m_DataList;  // 数据容器  
        public BaseDevice()
        {
            _DevId = 0;
            _isConnected = false;                // 连接状态
            _isWorking = false;                  // 是否启用
            _iNoReceive = 0;                     // 无接收次数
            _BreakCnt = 5;
        }
    }
    [StructLayout(LayoutKind.Sequential)]
    public class DevDataItem  // 数据项基类
    {
        public int   ItemId;                        // "数据点号",  用于插帧读取时，数据解析对点
        public string Name = "";
        private byte[] _RawBytes = new byte[8];     
        public byte[] RawBytes                      // 原始报文字节数组（8字节）
        {
            get { return _RawBytes; }
            set { _RawBytes = value; }
        }
        private double _dCurValue;                  // "数值",
        public double dCurValue                     // 当前值
        {
            get { return _dCurValue; }
            set
            {
                _dCurValue = value;
                dAverage = value;
                dMaxValue = value;
                dMinValue = value;
            }
        }
        public byte bFunCode;                       // "功能码",hide
        public ushort usRegAddr;                    // "地址", hide
        public eDataType dataType= eDataType.INT32; // "值类型",hide
        private string _strFormat = "f3";
        public string strFormat                     // 显示格式 （在fmult值改变时设置）
        {
            get { return _strFormat; }
            protected set { _strFormat = value; }
        }
        private int _PointNum;
        public int PointNum                         // 显示小数点
        {
            get { return _PointNum; }
            protected set { _PointNum = value; }
        }                       
        private double _fmult;                       // "倍率"   hide
        private double? _dMaxValue = null;
        public double? dMaxValue                     // 最大值
        {
            get { return _dMaxValue; }
            set 
            {
                if (_dMaxValue == null || value > _dMaxValue || (value == null))
                {
                    _dMaxValue = value;
                }
            }
        }
        private double? _dMinValue = null;
        public double? dMinValue                     // 最小值
        {
            get { return _dMinValue; }
            set
            {
                if (_dMinValue == null || value < _dMinValue || (value == null))
                {
                    _dMinValue = value;
                }
            }
        }
        private double _dAverage = 0;
        public int nRecCnt = 0;                     // 平均值计算样本数量（大于10000时重置为1）
        /// <summary>
        /// 平均值（把接收值直接赋值给平均值即可，内部自行计算）
        /// </summary>
        public double dAverage                      // 平均值
        {
            get { return _dAverage; }
            set 
            {
                _dAverage = (_dAverage * nRecCnt + value) / (nRecCnt + 1);
                nRecCnt++;
                if (nRecCnt >= 10000)
                {
                    nRecCnt = 1;
                }
            }
        }
        public double dmult                          // 缩放倍率
        {
            get { return _fmult; }
            set 
            {
                float fvalue;
                fvalue = (float)value;
               
                PointNum = 0;
                if (_fmult < 1)  // 计算显示精度
                {
                    string strPoint = fvalue.ToString();
                    PointNum = strPoint.Length - strPoint.IndexOf(".") - 1;
                }
                if (PointNum == 0)
                {
                    strFormat = "f0";
                    if (dataType == eDataType.FLOAT || dataType == eDataType.DOUBLE)
                    {
                        strFormat = "f3";
                        PointNum = 3;
                    }
                }
                else
                {
                    strFormat = string.Format("f{0}", PointNum);
                }
                _fmult = Math.Round(fvalue, PointNum);
            }
        }
        public bool IsSummation = true;                  // 是否读取
        public bool isLock;                         // 是否锁定
        public double dWriteValue;                  // 修改值 hide
        public bool IsSave = true;                  // 是否存储
        int _SaveT = 5;
        public int SaveCycle
        {
            get { return _SaveT; }
            set 
            { 
                if (value < 1)
                {
                    _SaveT = 1;
                }
                else
                {
                    _SaveT = value; 
                }
            }
        }                     // 存储周期
        public DateTime SaveTime = DateTime.Now;    // 上次存储时间
        //public int SaveCycle = 5;                 

        // 
        ScriptScope scode = null;
        private CompiledCode sourceCode = null;    // 编译的脚本
        private StringBuilder expression =  new StringBuilder();
        public string Expression                    // 用于脚本的表达式
        {
            get { return expression.ToString(); }
            set 
            {
                if (expression.ToString() != value && value!= null)
                {
                    expression.Clear();
                    expression.Append(value);
                    try
                    {
                        var code = AppMain.ScptEngine.CreateScriptSourceFromString(expression.ToString());
                        sourceCode = code.Compile();
                    }
                    catch (System.Exception ex)
                    {
                        sourceCode = null;
                        MessageBox.Show(ex.Message);
                    }
                }
            }
        }
        public bool isIgnore = false;               // 忽略脚本
        private string _customDisplay = "";
        public string CustomDisplay                 // 自定义显示
        {
            get 
            {
                if (isIgnore)
                {
                    return _customDisplay;
                }
                if (sourceCode != null)
                {
                    try
                    {
                        if (scode == null)
                        {
                            scode = AppMain.ScptEngine.CreateScope();
                            scode.SetVariable("bytes", RawBytes);  // 设置全局变量
                        }
                        var actual = sourceCode.Execute<object>(scode); //执行code脚本，获取输出值
                        _customDisplay = (actual != null ? actual.ToString():"");
                    }
                    catch 
                    {
                        sourceCode = null;
                        scode = null;
                        _customDisplay = "";
                    }
                    return _customDisplay;
                }
                else
                {
                    return "";
                } 
            }
            set { isIgnore = true; _customDisplay = value; }  // 外接设置值时忽略内部脚本
        }

        public DevDataItem()
        {
            Name = Resources.txtNewDataItem;
            dataType = eDataType.INT32;
        }
        public DevDataItem(string strItem, byte bFun, ushort regAddr, eDataType DataType, float Mult, bool bLock)
        {
            Name = strItem;
            dCurValue = 0;              // "数值",
            bFunCode = bFun;            // "功能码",hide
            usRegAddr = regAddr;        //  "地址", hide
            dataType = DataType;        // "值类型",hide
            dmult = Mult;               // "倍率"   hide
            isLock = bLock;             // 是否可修改
            dWriteValue = 0;            // 修改值 hide
        }
        public bool CopyFrom(DevDataItem dataItem)
        {
            ItemId = dataItem.ItemId;
            Name = dataItem.Name;
            dCurValue = dataItem.dCurValue;                    
            bFunCode = dataItem.bFunCode;                      
            usRegAddr = dataItem.usRegAddr;                    
            dataType = dataItem.dataType;                      
            dmult = dataItem.dmult;
            IsSummation = dataItem.IsSummation;               
            isLock = dataItem.isLock;                          
            dWriteValue = dataItem.dWriteValue;
            IsSave = dataItem.IsSave;
            SaveCycle = dataItem.SaveCycle;
            return true;
        }


    }
    public struct ErrMsg
    {
        public int ChlId;
        public int DevId;
        public DateTime RecT;
        public string strTxMsg;
        public string strRxMsg;
    }

}
